# LeetCode 82、删除排序链表中的重复元素 II(递归版)

# 一、题目描述

给定一个已排序的链表的头 head删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表

img

# 二、题目解析

# 三、参考代码

# 1、Java 代码

// 登录 AlgoMooc 官网获取更多算法图解
// https://www.algomooc.com
// 作者:程序员吴师兄
// 代码有看不懂的地方一定要私聊咨询吴师兄呀
// https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list-ii/submissions/
class Solution {
    public ListNode deleteDuplicates(ListNode head) {

        // 递归终止条件
        if(head == null || head.next == null){
            return head;
        }

        // 在访问过程中,会出现两种情况
        // 1、如果访问的节点值和下一个节点值不相同
        if(head.val != head.next.val){

            // 那么说明当前访问的节点 head 需要保留下来,它和后面经过删除操作的链表连接起来

            // a、利用递归,获取后续删除了链表重复元素的链表
            ListNode resNode = deleteDuplicates(head.next);

            // 将 head 和后续已经删除了重复元素的链表连接起来
            head.next = resNode;

            // 返回这个结果就行
            return head;

        // 2、如果访问的节点值和下一个节点值相同
        }else{

            // 那说明 head 这个节点就不应该留下来

            // 现在的目的就是去找出和 head 这个节点值不一样的节点来
            ListNode newNode = head.next;

            // 利用 while 循环,找出和 head 这个节点值不一样的节点来
            while(newNode != null && head.val == newNode.val){
                newNode = newNode.next;
            }

            // 此时,经过 while 循环后,newNode 指向了一个不等于 head 的节点
            // 递归调用 deleteDuplicates 函数,处理后面的所有节点
            // 处理好后
            // 1、要么是直接是最终的结果
            // 2、要么是这个结果链表会连接在某个节点后面,比如上述的 a 操作这行代码
            return deleteDuplicates(newNode);

        }

    }
}

# **2、**C++ 代码

// 登录 AlgoMooc 官网获取更多算法图解
// https://www.algomooc.com
// 作者:程序员吴师兄
// 代码有看不懂的地方一定要私聊咨询吴师兄呀
// https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list-ii/submissions/
class Solution {
public:
    ListNode* deleteDuplicates(ListNode* head) {
        // 递归终止条件
        if(head == NULL || head->next == NULL){
            return head;
        }

        // 在访问过程中,会出现两种情况
        // 1、如果访问的节点值和下一个节点值不相同
        if(head->val != head->next->val){

            // 那么说明当前访问的节点 head 需要保留下来,它和后面经过删除操作的链表连接起来

            // a、利用递归,获取后续删除了链表重复元素的链表
            ListNode *resNode = deleteDuplicates(head->next);

            // 将 head 和后续已经删除了重复元素的链表连接起来
            head->next = resNode;

            // 返回这个结果就行
            return head;

        // 2、如果访问的节点值和下一个节点值相同
        }else{

            // 那说明 head 这个节点就不应该留下来

            // 现在的目的就是去找出和 head 这个节点值不一样的节点来
            ListNode *newNode = head->next;

            // 利用 while 循环,找出和 head 这个节点值不一样的节点来
            while(newNode != NULL && head->val == newNode->val){
                newNode = newNode->next;
            }

            // 此时,经过 while 循环后,newNode 指向了一个不等于 head 的节点
            // 递归调用 deleteDuplicates 函数,处理后面的所有节点
            // 处理好后
            // 1、要么是直接是最终的结果
            // 2、要么是这个结果链表会连接在某个节点后面,比如上述的 a 操作这行代码
            return deleteDuplicates(newNode);

        }

    }
};

# 3、Python 代码

# 登录 AlgoMooc 官网获取更多算法图解
# https://www.algomooc.com
# 作者:程序员吴师兄
# 代码有看不懂的地方一定要私聊咨询吴师兄呀
# https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list-ii/submissions/
class Solution:
    def deleteDuplicates(self, head: ListNode) -> ListNode:
        # 递归终止条件
        if head == None or head.next == None:
            return head
        

        # 在访问过程中,会出现两种情况
        # 1、如果访问的节点值和下一个节点值不相同
        if head.val != head.next.val:

            # 那么说明当前访问的节点 head 需要保留下来,它和后面经过删除操作的链表连接起来

            # a、利用递归,获取后续删除了链表重复元素的链表
            resNode = self.deleteDuplicates(head.next)

            # 将 head 和后续已经删除了重复元素的链表连接起来
            head.next = resNode

            # 返回这个结果就行
            return head

        # 2、如果访问的节点值和下一个节点值相同
        else:

            # 那说明 head 这个节点就不应该留下来

            # 现在的目的就是去找出和 head 这个节点值不一样的节点来
            newNode = head.next

            # 利用 while 循环,找出和 head 这个节点值不一样的节点来
            while newNode != None and head.val == newNode.val:
                newNode = newNode.next
            

            # 此时,经过 while 循环后,newNode 指向了一个不等于 head 的节点
            # 递归调用 deleteDuplicates 函数,处理后面的所有节点
            # 处理好后
            # 1、要么是直接是最终的结果
            # 2、要么是这个结果链表会连接在某个节点后面,比如上述的 a 操作这行代码
            return self.deleteDuplicates(newNode)

# 四、复杂度分析

  • 时间复杂度:O(n),其中 n 是链表的长度。
  • 空间复杂度:O(n)。